package com.ruoyi.quality.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.Defect;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.quality.domain.QualityUserClassification;
import com.ruoyi.quality.domain.bo.QualityClassificationDataBo;
import com.ruoyi.quality.domain.bo.QualityUserClassificationBo;
import com.ruoyi.quality.domain.vo.QualityClassificationDataVo;
import com.ruoyi.quality.domain.vo.QualityUserClassificationVo;
import com.ruoyi.quality.mapper.QualityUserClassificationMapper;
import com.ruoyi.quality.service.IQualityClassificationDataService;
import com.ruoyi.quality.service.IQualityUserClassificationService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * 用户分级Service业务层处理
 *
 * @author ruoyi
 * @date 2023-12-18
 */
@RequiredArgsConstructor
@Service
public class QualityUserClassificationServiceImpl implements IQualityUserClassificationService {

    private final QualityUserClassificationMapper baseMapper;

    private final IQualityClassificationDataService iQualityClassificationDataService;

    /**
     * 查询用户分级
     */
    @Override
    public QualityUserClassificationVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询用户分级
     */
    @Override
    public QualityUserClassificationVo queryByBo(QualityUserClassificationBo bo){
        LambdaQueryWrapper<QualityUserClassification> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getUserName()), QualityUserClassification::getUserName, bo.getUserName());
        lqw.eq(bo.getId()!= null, QualityUserClassification::getId, bo.getId());
        return baseMapper.selectVoOne(lqw);
    }

    /**
     * 查询用户分级
     */
    @Override
    public List<QualityUserClassificationVo> queryByIds(Collection<Long> ids){
        return baseMapper.selectVoBatchIds(ids);
    }

    /**
     * 查询用户分级列表
     */
    @Override
    public TableDataInfo<QualityUserClassificationVo> queryPageList(QualityUserClassificationBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<QualityUserClassification> lqw = buildQueryWrapper(bo);
        Page<QualityUserClassificationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询用户分级列表
     */
    @Override
    public List<QualityUserClassificationVo> queryList(QualityUserClassificationBo bo) {
        LambdaQueryWrapper<QualityUserClassification> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<QualityUserClassification> buildQueryWrapper(QualityUserClassificationBo bo) {
        LambdaQueryWrapper<QualityUserClassification> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getUserName()), QualityUserClassification::getUserName, bo.getUserName());
        lqw.eq(bo.getTheory() != null, QualityUserClassification::getTheory, bo.getTheory());
        lqw.eq(bo.getPractice() != null, QualityUserClassification::getPractice, bo.getPractice());
        lqw.eq(bo.getExamine() != null, QualityUserClassification::getExamine, bo.getExamine());
        lqw.eq(bo.getTotal() != null, QualityUserClassification::getTotal, bo.getTotal());
        lqw.like(StringUtils.isNotBlank(bo.getClassification()), QualityUserClassification::getClassification, bo.getClassification());
        lqw.eq(StringUtils.isNotBlank(bo.getFlag()), QualityUserClassification::getFlag, bo.getFlag());
        // 添加根据 Total 字段降序排序
        lqw.orderByDesc(QualityUserClassification::getTotal);
        // 添加根据 id 字段升序排序
        lqw.orderByDesc(QualityUserClassification::getTotal);
        // 添加根据 id 字段升序排序
        lqw.orderByAsc(QualityUserClassification::getId);
        if (bo.getUserNameList() != null) {
            lqw.in(QualityUserClassification::getUserName, Arrays.asList(bo.getUserNameList()));
        }
        return lqw;
    }

    private BigDecimal getMostPracticeScore() {
        LambdaQueryWrapper<QualityUserClassification> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(QualityUserClassification::getPractice);
        List<QualityUserClassificationVo> voList = baseMapper.selectVoList(lqw);
        if (voList.size() > 0) {
            QualityUserClassificationVo vo = voList.get(0);
            if (vo == null || vo.getPractice().equals(BigDecimal.ZERO)) {
                return BigDecimal.valueOf(Defect.PRACTICE_SCORE);
            } else {
                return vo.getPractice();
            }
        } else {
            return BigDecimal.valueOf(Defect.PRACTICE_SCORE);
        }
    }

    /**
     * 新增用户分级
     */
    @Override
    public Boolean insertByBo(QualityUserClassificationBo bo) {
        QualityUserClassification add = BeanUtil.toBean(bo, QualityUserClassification.class);
        validEntityBeforeSave(add);
        BigDecimal total = getTotalByBo(bo);
        String flag = add.getFlag();
        add.setTotal(total);
        add.setClassification(updateClassificationByTotal(total,flag));
        boolean status = baseMapper.insert(add) > 0;
        if (status) {
            bo.setId(add.getId());
        }
        return status;
    }

    /**
     * 修改用户分级
     */
    @Override
    public Boolean updateByBo(QualityUserClassificationBo bo) {
        QualityUserClassification update = BeanUtil.toBean(bo, QualityUserClassification.class);
        validEntityBeforeSave(update);
        BigDecimal total = getTotalByBo(bo);
        String flag = update.getFlag();
        update.setTotal(total);
        update.setClassification(updateClassificationByTotal(total,flag));
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 更新实操分
     */
    @Override
    public Boolean updatePracticeByDataBo(QualityClassificationDataBo bo) {
        try {
            QualityUserClassificationBo update = new QualityUserClassificationBo();
            String userName = String.valueOf(bo.getUserId());
            BigDecimal decimal = iQualityClassificationDataService.queryTotalByUserId(Long.valueOf(userName));
            update.setUserName(userName);
            QualityUserClassificationVo userClassification = baseMapper.selectVoOne(buildQueryWrapper(update));
            update.setPractice(decimal);
            if (userClassification == null) {
                return insertByBo(update);
            }else {
                update.setId(userClassification.getId());
                return updateByBo(update);
            }
        } catch (NumberFormatException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 更新总分
     */
    @Override
    public BigDecimal getTotalByBo(QualityUserClassificationBo bo) {
        BigDecimal theory = bo.getTheory() != null ? bo.getTheory() : BigDecimal.ZERO;
        BigDecimal examine = bo.getExamine() != null ? bo.getExamine() : BigDecimal.ZERO;
        BigDecimal practice = bo.getPractice() != null ? bo.getPractice() : BigDecimal.ZERO;
        BigDecimal mostPractice = getMostPracticeScore();
        return practice
                .multiply(BigDecimal.valueOf(Defect.PRACTICE_PROPORTION))
                .multiply(BigDecimal.valueOf(Defect.PRACTICE_SCORE))
                .divide(mostPractice, 2, RoundingMode.HALF_UP)
                .add(theory.multiply(BigDecimal.valueOf(Defect.THEORY_PROPORTION)))
                .subtract(examine.divide(BigDecimal.valueOf(1000),2, RoundingMode.HALF_UP));
    }

    /**
     * 更新实操分
     *
     * @return 更新实操分数
     */
    @Override
    public Boolean deleteTotalByDataIds(Collection<Long> ids) {
        ids.forEach(id -> {
            QualityClassificationDataVo vo = iQualityClassificationDataService.queryById(id);
            QualityClassificationDataBo bo = BeanUtil.toBean(vo, QualityClassificationDataBo.class);
            updatePracticeByDataBo(bo);
        });
        return true;
    }

    /**
     * 根据总分更新等级
     */
    @Override
    public String updateClassificationByTotal(BigDecimal total, String flag) {
        BigDecimal thresholdAPlus = new BigDecimal(Defect.APlus_SCORE);
        BigDecimal thresholdA = new BigDecimal(Defect.A_SCORE);
        BigDecimal thresholdBPlus = new BigDecimal(Defect.BPlus_SCORE);
        BigDecimal thresholdB = new BigDecimal(Defect.B_SCORE);
        BigDecimal thresholdBMinus = new BigDecimal(Defect.BMinus_SCORE);

        if (!flag.equals("1")) {
            if (total.compareTo(thresholdAPlus) >= 0) {
                return "A+";
            } else if (total.compareTo(thresholdA) >= 0) {
                return "A";
            } else if (total.compareTo(thresholdBPlus) >= 0) {
                return "B+";
            } else if (total.compareTo(thresholdB) >= 0) {
                return "B";
            } else if (total.compareTo(thresholdBMinus) >= 0) {
                return "B-";
            }
        } else {
            if (total.compareTo(thresholdBMinus) >= 0) {
                return "B-";
            }
        }
        return "C";
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(QualityUserClassification entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除用户分级
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
